package model;

import gui.View;

public class Rectangle {

	/**
	 * @Smell   : Lazy class.
	 * @Refactor: Inline class.
	 * *** Highly related to question 3: No point of introducing getter-methods then!
	 */
	private Interval horizontal;
	private Interval vertical;
	private View view;

	public Rectangle(View view, int startX, int startY, int endX, int endY) {
		if ((startX > endX) || (startY > endY))
			throw new IllegalArgumentException("Parameters in wrong order.");
		init(new Interval(startX, endX), new Interval(startY, endY), view);
	}

	/**
	 * Create an empty Rectangle with no location.
	 */
	public Rectangle(View view) {
		init(null, null, view);
	}
	
	/**
	 * @Smell   : Duplication.
	 * @Refactor: Extract Method.
	 */
	private void init(Interval horizontal, Interval vertical, View view) {
		this.horizontal = horizontal;
		this.vertical = vertical;
		this.view = view;
		view.rectangle = this;
	}

	public Vertex getCenter() {
		if (horizontal == null)
			return null;
		return new Vertex((horizontal.start + horizontal.end) / 2,
				(vertical.start + vertical.end) / 2);
	}

	public boolean contains(Rectangle parameter) {
		if (parameter.horizontal == null)
			return false;
		if (horizontal == null)
			return false;
		
		return 
			containsIntervalInAnotherRectangle(horizontal.start, parameter.horizontal.start, horizontal.end, parameter.horizontal.end) && 
			containsIntervalInAnotherRectangle(vertical.start, parameter.vertical.start, vertical.end, parameter.vertical.end);
	}

	/**
	 * @Smell   : Comments.
	 * @Refactor: Extract Method.
	 * Check whether the horizontal (or vertical) interval contains 
	 * the horizontal (or vertical) interval in the other rectangle.
	 */
	private boolean containsIntervalInAnotherRectangle(int start, int parameterStart, int end, int parameterEnd) {
		return (start <= parameterStart) && (parameterEnd <= end);
	}
	
	/**
	 * @Smell   : Feature Envy.
	 * @Refactor: Move Method.
	 * Enlarge the Rectangle just enough so that it contains the other
	 * Rectangle. If the Rectangle was empty it gets the same extension as the
	 * other Rectangle.
	 */
	public void accommodate(Rectangle other) {
		if ((other == null) || (other.horizontal == null))
			return;
		if (horizontal == null) {
			horizontal = new Interval(other.horizontal);
			vertical = new Interval(other.vertical);
			return;
		}
		horizontal.acommodate(other.horizontal);
		vertical.acommodate(other.vertical);
		view.redraw();
	}
	
	public boolean equals(Object obj) {
		if (!(obj instanceof Rectangle))
			return false;
		Rectangle other = (Rectangle) obj;
		if (horizontal == null)
			return (other.horizontal == null);
		return (horizontal.equals(other.horizontal))
				&& (vertical.equals(other.vertical));
	}

	public String toString() {
		return "Rectangle(" + horizontal + " x " + vertical + ")";
	}

	public Vertex getBottomLeft() {
		if (horizontal == null)
			return null;
		return new Vertex(horizontal.start, vertical.start);
	}

	public Object getTopRight() {
		if (horizontal == null)
			return null;
		return new Vertex(horizontal.end, vertical.end);
	}

	public void accommodate(Vertex vertex) {
		accommodate(new Rectangle(view, vertex.x, vertex.y, vertex.x, vertex.y));
	}
}
